package com.accp.wxmp.util;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.SortedMap;
import java.util.TreeMap;

public class WxUtil {

    //获取用户基本信息url
    private static String getUserInfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?";
    //获取access_token的url
    private static String getAccess_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
    //获取JSApi接口的url
    private static String getJsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
    //获取校验用户的url
    public static String wx_authorize_url = "https://open.weixin.qq.com/connect/oauth2/authorize";
    //获取刷新token的url
    public static String wx_refresh_token_url = "https://api.weixin.qq.com/sns/oauth2/refresh_token";

    //下载文件url
    private static String wx_download_url = "http://file.api.weixin.qq.com/cgi-bin/media/get";
    //	private static PubConfig pubConfig = (PubConfig) SpringContextHolder.getBean("pubConfig");
    //发送消息
    private static String send_msg_url = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
    //创建菜单url
    private static String wx_create_menu_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=";
    // 素材上传(POST)
    private static final String upload_media_url = "https://api.weixin.qq.com/cgi-bin/media/upload";

    private static Logger logger = LoggerFactory.getLogger("operationLog");



    /**
     * 获取access_token
     *
     * @return
     */
    public synchronized static String getAccessToken(String appid, String appsecret) {
        String access_token ="";
            String url = getAccess_token_url + "&appid=" + appid + "&secret=" + appsecret;
            String getJson = HttpUtil.getJsonFromUrl(url);
            HashMap<String, String> hashMap = JsonUtil.toHashmap(getJson);
            if (hashMap != null && hashMap.containsKey("access_token")) {
                access_token = hashMap.get("access_token");
            } else {
                access_token = "";
            }

        return access_token;
    }



    /**
     * 发送消息
     *
     * @param openid
     * @param text
     * @return
     */
    public static void sendMsg(String openid, String text, String appid, String appsecret) {
        String url = send_msg_url + "?access_token=" + getAccessToken(appid, appsecret);
        String jsonParam = "{\"touser\":\"" + openid + "\",\"msgtype\":\"text\", \"text\":{\"content\":\"" + text + "\"}}";
        HttpUtil.getJsonFromUrlPost(url, jsonParam);
    }

    /**
     * 发送图片消息
     *
     * @param openid
     * @return
     */
//    public  void sendImgMsg(String openid, String appid, String appsecret) {
//        //先判断当前时间和生成分享二维码的时间是否大于72小时，如果大于，则重新生成，否则直接发送图片至微信客户端
//        String media_id;
//        //	生成二维码
//        media_id = createShareQr();
//        String url = send_msg_url + "?access_token=" + getAccessToken(appid, appsecret);
//        String jsonParam = "{\"touser\":\"" + openid + "\",\"msgtype\":\"image\", \"image\":{\"media_id\":\"" + media_id + "\"}}";
//        HttpUtil.getJsonFromUrlPost(url, jsonParam);
//    }

    /**
     * 生成分享的二维码
     */
//    private static String createShareQr() {
//        String media_id = "";
//        try {
//            ///上传该图片至微信服务器
//            File qrshare = new File(pubConfig.getImageUploadPath() + File.separator + "qrshare" + File.separator + DateUtil.getShortSystemDate() + File.separator + DateUtil.getShortSystemTime() + SerialNumUtil.createRandowmNum(6) + ".jpg");
//            media_id = WxUtil.uploadImg(WxUtil.getAccessToken("Appid", "Appsecret"), qrshare);
//            //修改代言人对应share_qrcode字段
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return media_id;
//    }



    /**
     * 这里说下，在上传视频素材的时候，微信说不超过20M，我试了下，超过10M调通的可能性都比较小，建议大家上传视频素材的大小小于10M比交好
     *
     * @param accessToken
     * @param file        上传的文件
     */
    public static String uploadImg(String accessToken, File file) {
        LogUtil.infoSys("请求url：" + upload_media_url);
        String media_id = "";
        URL url = null;
        HttpURLConnection con = null;
        OutputStream out = null;
        DataInputStream in = null;
        BufferedReader reader = null;
        try {
            // 拼装请求地址

            url = new URL(upload_media_url + "?access_token=" + accessToken);
            String result = null;
            long filelength = file.length();
            String fileName = file.getName();
            String type = "image"; //我这里写死
            // 你们需要在这里根据文件后缀suffix将type的值设置成对应的mime类型的值
            con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("POST"); // 以Post方式提交表单，默认get方式
            con.setDoInput(true);
            con.setDoOutput(true);
            con.setUseCaches(false); // post方式不能使用缓存
            // 设置请求头信息
            con.setRequestProperty("Connection", "Keep-Alive");
            con.setRequestProperty("Charset", "UTF-8");

            // 设置边界,这里的boundary是http协议里面的分割符，不懂的可惜百度(http 协议 boundary)，这里boundary 可以是任意的值(111,2222)都行
            String BOUNDARY = "----------" + System.currentTimeMillis();
            con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            // 请求正文信息
            // 第一部分：

            StringBuilder sb = new StringBuilder();

            //这块是post提交type的值也就是文件对应的mime类型值
            sb.append("--"); // 必须多两道线 这里说明下，这两个横杠是http协议要求的，用来分隔提交的参数用的，不懂的可以看看http 协议头
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"type\" \r\n\r\n"); //这里是参数名，参数名和值之间要用两次
            sb.append(type + "\r\n"); //参数的值

            //这块是上传video是必须的参数，你们可以在这里根据文件类型做if/else 判断
            sb.append("--"); // 必须多两道线
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"description\" \r\n\r\n");
            sb.append("\r\n");

            /**
             * 这里重点说明下，上面两个参数完全可以卸载url地址后面 就想我们平时url地址传参一样，
             * http://api.weixin.qq.com/cgi-bin/material/add_material?access_token=##ACCESS_TOKEN##&type=""&description={} 这样，如果写成这样，上面的
             * 那两个参数的代码就不用写了，不过media参数能否这样提交我没有试，感兴趣的可以试试
             */

            sb.append("--"); // 必须多两道线
            sb.append(BOUNDARY);
            sb.append("\r\n");
            //这里是media参数相关的信息，这里是否能分开下我没有试，感兴趣的可以试试
            sb.append("Content-Disposition: form-data;name=\"media\";filename=\"" + fileName + "\";filelength=\"" + filelength + "\" \r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            byte[] head = sb.toString().getBytes("utf-8");
            // 获得输出流
            out = new DataOutputStream(con.getOutputStream());
            // 输出表头
            out.write(head);
            // 文件正文部分
            // 把文件已流文件的方式 推入到url中
            in = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            // 结尾部分，这里结尾表示整体的参数的结尾，结尾要用"--"作为结束，这些都是http协议的规定
            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
            out.write(foot);
            StringBuffer buffer = new StringBuffer();

            // 定义BufferedReader输入流来读取URL的响应
            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            if (result == null) {
                result = buffer.toString();
            }

            HashMap<String, String> hashMap = JsonUtil.toHashmap(result);
            media_id = hashMap.get("media_id");
            LogUtil.infoSys("请求结果：" + result);
        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.infoSys(e.getMessage());
        } finally {
            try {
                out.flush();
                out.close();
                in.close();
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            con.disconnect();
        }
        return media_id;
    }
}
